<?php
/**
 * RsaUtil.php
 * Created by PhpStorm.
 * User: 江小波
 * Date: 2018/8/17
 * Time: 11:05
 */
namespace app\common\utils\rsa;
/**
 * 私钥加密 ==> 公钥解密
 * 公钥加密 ==> 私钥解密
 * 私钥加密 =/=> 私钥不能解密
 * 公钥加密 =/=> 公钥不能解密
 */
class RsaUtil {
    /**
     * 通过私钥加密数据
     * @Title: encryptByPri
     * @Description: todo(加密数据字符串)
     * @author: jiangbo <18883870892@163.com>
     * @date: 2017年12月11日 下午14:59:35
     * @throws
     */
    static public function encryptByPri($data,$private_key=''){
        // openssl genrsa -out rsa_private_key.pem 1024
        if(empty($private_key)) $private_key = RsaConf::PRIVATE_KEY;
        // 这个函数可用来判断私钥是否是可用的，可用返回资源id Resource id
        $pi_key = openssl_pkey_get_private($private_key);
        // rsa 是否可用
        if($pi_key === false) throw new \Exception("rsa is not available",1);

        // 私钥加密返回参数
        $encrypted = "";
        openssl_private_encrypt(is_string($data)?$data:json_encode($data), $encrypted, $pi_key);
        // 加密后的内容通常含有特殊字符，需要编码转换下，在网络间通过url传输时要注意base64编码是否是url安全的
        // 加密码时把特殊符号替换成URL可以带的内容
        return str_replace(array('+','/','='),array('-','_',''),base64_encode($encrypted));
        // return base64_encode($encrypted);
    }
    /**
     * 通过私钥解密数据
     * @Title: decryptByPri
     * @Description: todo(解密数据)
     * @author: jiangbo <18883870892@163.com>
     * @date: 2017年12月11日 下午14:59:35
     * @throws
     */
    static public function decryptByPri($data,$private_key=''){
        // openssl genrsa -out rsa_private_key.pem 1024
        if(empty($private_key)) $private_key = RsaConf::PRIVATE_KEY;
        // 这个函数可用来判断私钥是否是可用的，可用返回资源id Resource id
        $pi_key = openssl_pkey_get_private($private_key);
        // rsa 是否可用
        if($pi_key === false) throw new \Exception("rsa is not available",1);
        // 私钥解密
        $decrypted = "";
        // openssl_private_decrypt(base64_decode($data), $decrypted, $pi_key);
        openssl_private_decrypt(base64_decode(str_replace(array('-','_'),array('+','/'),$data)), $decrypted, $pi_key);
        // 取出解密之后的json字符串参数
        return $decrypted;
    }
    /**
     * 通过公钥加密数据
     * @Title: encryptByPub
     * @Description: todo(加密数据字符串)
     * @author: jiangbo <18883870892@163.com>
     * @date: 2017年12月11日 下午14:59:35
     * @throws
     */
    static public function encryptByPub($data,$public_key=''){
        // openssl genrsa -out rsa_public_key.pem 1024
        if(empty($public_key)) $public_key = RsaConf::PUBLIC_KEY;
        // 这个函数可用来判断公钥是否是可用的，可用返回资源id Resource id
        $pu_key = openssl_pkey_get_public($public_key);
        // rsa 是否可用
        if($pu_key === false) throw new \Exception("rsa is not available",1);

        // 公钥加密返回参数
        $encrypted = "";
        openssl_public_encrypt(is_string($data)?$data:json_encode($data), $encrypted, $pu_key);
        // 加密后的内容通常含有特殊字符，需要编码转换下，在网络间通过url传输时要注意base64编码是否是url安全的
        // 加密码时把特殊符号替换成URL可以带的内容
        return str_replace(array('+','/','='),array('-','_',''),base64_encode($encrypted));
        // return base64_encode($encrypted);
    }
    /**
     * 通过公钥解密数据
     * @Title: decryptByPub
     * @Description: todo(解密数据)
     * @author: jiangbo <18883870892@163.com>
     * @date: 2017年12月11日 下午14:59:35
     * @throws
     */
    static public function decryptByPub($data,$public_key=''){
        // openssl genrsa -out rsa_public_key.pem 1024
        if(empty($public_key)) $public_key = RsaConf::PUBLIC_KEY;
        // 这个函数可用来判断公钥是否是可用的，可用返回资源id Resource id
        $pu_key = openssl_pkey_get_public($public_key);
        // rsa 是否可用
        if($pu_key === false) throw new \Exception("rsa is not available",1);

        // 公钥解密
        $decrypted = "";
        // openssl_public_decrypt(base64_decode($data), $decrypted, $pu_key);
        openssl_public_decrypt(base64_decode(str_replace(array('-','_'),array('+','/'),$data)), $decrypted, $pu_key);
        // 取出解密之后的json字符串参数
        return $decrypted;
    }
}